﻿namespace TomatoBreak.DataAccess
{
    using System;
    using System.Linq;
    using System.Linq.Expressions;

    using NHibernate;
    using NHibernate.Linq;

    using DomainObjects;

    public class Repository<T> : IRepository<T> where T : Entity
    {
        private readonly ISession session;

        public Repository(ISession session)
        {
            if (session == null)
            {
                throw new ArgumentNullException("session");
            }

            this.session = session;
        }

        public virtual void Add(T instance)
        {
            session.Save(instance);
        }

        public virtual void Update(T instance)
        {
            session.SaveOrUpdate(instance);
        }

        public virtual void Remove(T instance)
        {
            session.Delete(instance);
        }

        public virtual bool Exists(Expression<Func<T, bool>> predicate)
        {
            return session.Query<T>().Any(predicate);
        }

        public virtual int Count()
        {
            return session.Query<T>().Count();
        }

        public virtual int Count(Expression<Func<T, bool>> predicate)
        {
            return session.Query<T>().Count(predicate);
        }

        public virtual T One(Guid id)
        {
            return session.Get<T>(id);
        }

        public virtual T FindOne(Expression<Func<T, bool>> predicate)
        {
            return session.Query<T>().FirstOrDefault(predicate);
        }

        public virtual IQueryable<T> FindAll(
            Expression<Func<T, bool>> predicate)
        {
            return session.Query<T>().Where(predicate);
        }

        public virtual IQueryable<T> All()
        {
            return session.Query<T>();
        }
    }
}